﻿using CoreLims.Models.CoreLims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace CoreLims.Controllers
{
    [Authorize(Roles = "Admin,试剂管理")]
    public class ReagentController : Controller
    {
        public static Reagent Reagent;

        private readonly CoreLimsContext dbContext;
        public ReagentController(CoreLimsContext context)
        {
            dbContext = context;
        }

        public ViewResult ReagentManage() => View();

        public ViewResult AddReagents() => View();

        [HttpPost]
        public ViewResult AddComponent(string ReagentsId, string ComponentId, string ModalID)
        {
            ViewData["ReagentsId"] = ReagentsId;
            ViewData["ComponentId"] = ComponentId;
            ViewData["ModalID"] = ModalID;
            return View();
        }

        [HttpPost]
        public ViewResult ComponentMethod(string ComponentId, string ModalID)
        {
            ViewData["ComponentId"] = ComponentId;
            ViewData["ModalID"] = ModalID;
            return View();
        }

        [HttpPost]
        public ViewResult PreparationOfReagents(string ReagentsId)
        {
            ViewData["ReagentsId"] = ReagentsId;
            return View();
        }

        [HttpPost]
        public JsonResult GetReagentType() //获取 type 数组
        {
            var list = Reagent.getReagents(dbContext)
                .Distinct(new Reagent.ReagentsTypeCompare()).Select(s => new { s.Type });
            return Json(list);
        }

        [HttpPost]
        public JsonResult GetRecordType() //获取 type 数组
        {
            var list = Reagent.getRecords(dbContext)
                .Distinct(new Reagent.RecordTypeCompare()).Select(s => new { s.Type });
            return Json(list);
        }

        [HttpPost]
        public JsonResult GetReagentsByType(string Type, string limit, string offset)
        {
            var list = Reagent.getReagents(dbContext)
                .Where(m => m.Type == Type)
                .OrderBy(s => s.Name)
                .Skip(int.Parse(offset)).Take(int.Parse(limit))
                .ToArray();

            var res = new Common.PageHelper();
            res.total = Reagent.getReagents(dbContext).Where(m => m.Type == Type).ToList().Count;
            res.rows = list;

            return Json(res);
        }

        [HttpPost]
        public JsonResult GetReagentById(string Id)
        {
            var reagent = Reagent.getReagents(dbContext)
                .Where(m => m.Id == Id).FirstOrDefault();
            return Json(reagent);
        }

        [HttpPost]
        public JsonResult GetComponentsByReagentId(string ReagentsId, string limit, string offset)
        {
            var list = Reagent.getComponentsByReagentId(dbContext, ReagentsId)
                .OrderBy(s => s.Name)
                .Skip(int.Parse(offset)).Take(int.Parse(limit))
                .Select(s => new {s.Id, s.Name, s.Concentration, s.MaterialCode, s.MaterialName, s.Dosage, s.DosageUnit})
                .ToArray();

            var res = new Common.PageHelper();
            res.total = Reagent.getComponentsByReagentId(dbContext, ReagentsId).ToList().Count;
            res.rows = list;

            return Json(res);
        }

        [HttpPost]
        public JsonResult getRecordsByReagentId(string ReagentId, string limit, string offset)
        {
            var list = Reagent.getRecordsByReagentId(dbContext, ReagentId)
                .OrderByDescending(s => s.PreparationTime)
                .Skip(int.Parse(offset)).Take(int.Parse(limit))
                .ToArray();

            var res = new Common.PageHelper();
            res.total = Reagent.getRecordsByReagentId(dbContext, ReagentId).ToList().Count;
            res.rows = list;

            return Json(res);
        }

        [HttpPost]
        public string getComponentMethod(string ComponentId)
        {
            return Reagent.getComponent(dbContext, ComponentId).PreparationMethod;
        }

        [HttpPost]
        public JsonResult getComponent(string ComponentId)
        {
            return Json(Reagent.getComponent(dbContext, ComponentId));
        }

        [HttpPost]
        public JsonResult GetRecords(string ReagentId, string limit, string offset)
        {
            var list = Reagent.getRecords(dbContext)
                .Where(m => m.ReagentId == ReagentId)
                .OrderByDescending(s => s.PreparationTime)
                .Skip(int.Parse(offset)).Take(int.Parse(limit))
                .ToArray();

            var res = new Common.PageHelper();
            res.total = Reagent.getRecords(dbContext).Where(m => m.ReagentId == ReagentId).ToList().Count;
            res.rows = list;

            return Json(res);
        }

        [HttpPost]
        public string UpdateReagent(string jsonStr)
        {
            try
            {
                var reagent = JsonConvert.DeserializeObject<Reagent.Reagents>(jsonStr);
                dbContext.Update(reagent);
                dbContext.SaveChanges();
                return "试剂信息更新成功！";
            }
            catch (Exception ex)
            { return ex.Message; }
        }

        [HttpPost]
        public string UpdateComponentMethod(string ComponentId, string method)
        {
            var reagent = Reagent.getComponent(dbContext, ComponentId);
            reagent.PreparationMethod = method;
            dbContext.Update(reagent);
            dbContext.SaveChanges();
            return "配制方法更新成功！";
        }

        [HttpPost]
        public string UpdateComponent(string jsonStr, string IsInventory)
        {
            try
            {
                var component = JsonConvert.DeserializeObject<Reagent.Component>(jsonStr);  //反序列化
                if (IsInventory == "是")
                    component.IsInventory = true;

                var oldcomponent = Reagent.getComponent(dbContext, component.Id);
                oldcomponent.Copy(component);

                dbContext.Update(oldcomponent);
                dbContext.SaveChanges();
                return "组份更新成功！";
            }
            catch (Exception ex)
            { return ex.Message; }
        }

        [HttpPost]
        public string postAddReagents(string jsonStr)
        {
            try
            {
                var reag = JsonConvert.DeserializeObject<Reagent.Reagents>(jsonStr);  //反序列化
                dbContext.Add(reag);
                dbContext.SaveChanges();
                return "试剂添加成功！";
            }
            catch(Exception ex)
            { return ex.Message;  }
        }

        [HttpPost]
        public string postAddComponent(string jsonStr, string IsInventory)
        {
            try
            {
                var component = JsonConvert.DeserializeObject<Reagent.Component>(jsonStr);  //反序列化
                if (IsInventory == "是")
                    component.IsInventory = true;

                dbContext.Add(component);
                dbContext.SaveChanges();
                return "组份添加成功！";
            }
            catch(Exception ex)
            { return ex.Message;  }
        }

        [HttpPost]
        public string postAddRecord(string jsonStr)
        {
            try
            {
                var other = JsonConvert.DeserializeObject<Reagent.Record>(jsonStr);
                var reagent = Reagent.getReagents(dbContext, other.ReagentId);
                var record = Reagent.Record.Copy(other, reagent);

                var user = Common.User.getUserByIdentityName(dbContext, HttpContext.User.Identity.Name); 
                var ruser = Common.User.getUserByIdentityName(dbContext, "admin");
                record.PreparationById = user.Id;
                record.PreparationByName = user.FullName;

                if (!record.MaterialCode.IsNullOrEmpty())
                {
                    var st = INV.Inventory.AutoInventoryByReagentRecord(dbContext, record);
                    if (st.Contains("失败"))
                        return st;
                }

                var list = Reagent.getComponentsByReagentId(dbContext, other.ReagentId);
                dbContext.Record.Add(record);
                dbContext.SaveChanges();
                var rst = "配制记录添加成功！";

                foreach ( var component in list)
                {
                    if (!component.MaterialCode.IsNullOrEmpty() && component.IsInventory) 
                    {
                        var re = INV.Inventory.AutoUseOutInventory
                            (dbContext, component.MaterialCode, component.Dosage, component.DosageUnit, "Reagent.Component", component.Id);
                        if (!re.Contains("成功"))
                        {
                            var audit = Audit.newAudit;
                            audit.EventName = "自动领用库存";
                            audit.TableName = "Controller postAddRecord";
                            audit.RecordId = record.Id;
                            audit.RemindUserId = ruser.Id; 
                            audit.RemindUserName = ruser.FullName;
                            audit.Explain = re + "本次领用数量为：" + component.Dosage.ToString() + component.DosageUnit;
                            audit.Snapshot = JsonConvert.SerializeObject(component);
                            dbContext.AuditTrail.Add(audit);
                            dbContext.SaveChanges();
                            rst = "本次试剂配制存在库存异常，请联系管理员！";
                        }
                    }
                }
                return rst;
            }
            catch (Exception ex)
            { return ex.Message; }
}

        [HttpPost]
        public string RemoveComponent(string ComponentId)
        {
            try
            {
                var component = Reagent.getComponent(dbContext, ComponentId);
                dbContext.Remove(component);
                dbContext.SaveChanges();
                return "组分删除成功！";
            }
            catch (Exception ex)
            { return ex.Message; }
        }

    }
}
